package com.ssy.lingxi.report.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.report.api.enums.MemberOperateTypeEnum;
import com.ssy.lingxi.report.api.enums.OperateDataSourceEnum;
import com.ssy.lingxi.report.api.vo.request.AddSubMemberVO;
import com.ssy.lingxi.report.api.vo.request.OperateNoticeVO;
import com.ssy.lingxi.report.api.vo.request.PurchasePortalRequest;
import com.ssy.lingxi.report.api.vo.response.PurchasePortalStatisticsVO;
import com.ssy.lingxi.report.constant.Constants;
import com.ssy.lingxi.report.dao.merchantmember.MemberDAO;
import com.ssy.lingxi.report.dao.order.ProcurementOrderDAO;
import com.ssy.lingxi.report.dao.purchase.BiddingDAO;
import com.ssy.lingxi.report.dao.purchase.InviteTenderDAO;
import com.ssy.lingxi.report.dao.purchase.PurchaseInquiryDAO;
import com.ssy.lingxi.report.dao.report.SubMemberReportDAO;
import com.ssy.lingxi.report.entity.report.*;
import com.ssy.lingxi.report.model.bo.MemberRoleBO;
import com.ssy.lingxi.report.model.bo.StatisticsMemberBO;
import com.ssy.lingxi.report.model.vo.response.MemberRegisterStatisticsDetailVO;
import com.ssy.lingxi.report.model.vo.response.MemberRegisterStatisticsVO;
import com.ssy.lingxi.report.repository.report.MemberDayReportRepository;
import com.ssy.lingxi.report.repository.report.MemberMonthReportRepository;
import com.ssy.lingxi.report.repository.report.PurchaseDayReportRepository;
import com.ssy.lingxi.report.repository.report.SubMemberReportRepository;
import com.ssy.lingxi.report.service.IMemberReportService;
import com.ssy.lingxi.report.utils.TimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 会员报表接口实现
 * @author 伍将
 * @date 2020/11/9
 * @version 2.0.0
 */
@Service
public class MemberReportServiceImpl implements IMemberReportService {

    private static final Logger logger = LoggerFactory.getLogger(MemberReportServiceImpl.class);

    @Resource
    private MemberDayReportRepository memberDayReportRepository;

    @Resource
    private MemberMonthReportRepository memberMonthReportRepository;

    @Resource
    private MemberDAO memberDAO;
    @Resource
    private PurchaseDayReportRepository purchaseDayReportRepository;
    @Resource
    private ProcurementOrderDAO procurementOrderDAO;
    @Resource
    private BiddingDAO biddingDAO;
    @Resource
    private InviteTenderDAO inviteTenderDAO;
    @Resource
    private PurchaseInquiryDAO purchaseInquiryDAO;
    @Resource
    private JPAQueryFactory queryFactory;
    @Resource
    private SubMemberReportRepository subMemberReportRepository;
    @Resource
    private SubMemberReportDAO subMemberReportDAO;

    /**
     * 会员注册日报表
     * @param startTime:
     * @param endTime:
     */
    @Override
    public void memberRegisterDayReport(LocalDateTime startTime, LocalDateTime endTime) {
        updateRegisterDayReportCommon(startTime, endTime);
    }

    /**
     * 公共更新注册日报表
     * @author 伍将
     * @date 2021/1/29
     * @param startTime: 开始时间
     * @param endTime: 结束时间
     **/
    @Transactional
    public void updateRegisterDayReportCommon(LocalDateTime startTime, LocalDateTime endTime) {
        List<StatisticsMemberBO> memberBOList = memberDAO.getStatisticsMemberByDay(startTime, endTime);
        if (memberBOList == null) {
            logger.info("没有查询到注册会员");
            return;
        }

        logger.info("统计日注册会员：{}-{}，共{}条数据", startTime, endTime, memberBOList.stream().mapToLong(StatisticsMemberBO::getCount).sum());

        // 新增前先删除旧数据
        memberDayReportRepository.deleteByDateTimeBetween(startTime, endTime);

        // 新增会员日报表数据
        List<MemberDayReportDO> reportDOList = memberBOList.stream().map(r -> {
            MemberDayReportDO reportDO = new MemberDayReportDO();
            reportDO.setDateTime(r.getDateTime());
            reportDO.setRoleName(r.getRoleName());
            reportDO.setCount(r.getCount());
            return reportDO;
        }).collect(Collectors.toList());
        memberDayReportRepository.saveAll(reportDOList);
    }

    /**
     * 会员注册月报表
     * @author 伍将
     * @date 2020/11/9
     * @param startTime: 开始时间
     * @param endTime: 结束时间
     **/
    @Transactional
    @Override
    public void memberRegisterMonthReport(LocalDateTime startTime, LocalDateTime endTime) {
        updateRegisterMonthReportCommon(startTime, endTime);
    }

    /**
     * 公共更新注册月报表
     * @author 伍将
     * @date 2021/1/29
     * @param startTime: 开始时间
     * @param endTime: 结束时间
     **/
    public void updateRegisterMonthReportCommon(LocalDateTime startTime, LocalDateTime endTime) {
        List<StatisticsMemberBO> memberBOList = memberDAO.getStatisticsMemberByMonth(startTime, endTime);
        if (memberBOList == null) {
            logger.info("没有查询到注册会员");
            return;
        }

        logger.info("统计月注册会员：{}-{}，共{}条数据", startTime, endTime, memberBOList.stream().mapToLong(StatisticsMemberBO::getCount).sum());

        // 新增前先删除旧数据
        memberMonthReportRepository.deleteByDateTimeBetween(startTime, endTime);

        // 新增会员日报表数据
        List<MemberMonthReportDO> reportDOList = memberBOList.stream().map(r -> {
            MemberMonthReportDO reportDO = new MemberMonthReportDO();
            reportDO.setDateTime(r.getDateTime());
            reportDO.setRoleName(r.getRoleName());
            reportDO.setCount(r.getCount());
            return reportDO;
        }).collect(Collectors.toList());
        memberMonthReportRepository.saveAll(reportDOList);
    }

    /**
     * 更新会员注册报表
     * @author 伍将
     * @date 2021/1/29
     * @param operateVO: 操作通知
     **/
    @Transactional
    @Override
    public void updateMemberRegisterReport(OperateNoticeVO operateVO) {

        // 如果不是会员待提交审核操作或不数量不增加时，无需更新注册会员
        if (!OperateDataSourceEnum.PLATFORM_MEMBER_VERIFY.getCode().equals(operateVO.getDataSource())
                || !MemberOperateTypeEnum.TO_BE_COMMIT_VALIFY.getCode().equals(operateVO.getReduceOperateType())
                || operateVO.getReduceCount() <= 0) {
            return;
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 更新会员注册日报表
        LocalDateTime dayStartTime = LocalDateTime.parse(DateUtil.date().toString("yyyy-MM-dd 00:00:00"), formatter);
        LocalDateTime dayEndTime = LocalDateTime.parse(DateUtil.date().toString("yyyy-MM-dd 23:59:59"), formatter);
        updateRegisterDayReportCommon(dayStartTime, dayEndTime);

        // 更新会员注册月报表
        LocalDateTime monthStartTime = LocalDateTime.parse(DateUtil.format(TimeUtil.getMonthFirstDay(DateUtil.date()), "yyyy-MM-dd 00:00:00"), formatter);
        LocalDateTime monthEndTime = LocalDateTime.parse(DateUtil.format(TimeUtil.getMonthLastDay(DateUtil.date()), "yyyy-MM-dd 23:59:59"), formatter);
        updateRegisterMonthReportCommon(monthStartTime, monthEndTime);
    }

    @Override
    public Wrapper<Void> addSubMemberRegisterReport(AddSubMemberVO operateVO) {
        //插入会员注册信息
        SubMemberReportDO subMember=new SubMemberReportDO();
        subMember.setMemberId(operateVO.getMemberId());
        subMember.setRoleId(operateVO.getRoleId());
        subMember.setDateTime(operateVO.getDateTime());
        subMemberReportRepository.saveAndFlush(subMember);
        return Wrapper.success();
    }

    /**
     * 获取会员注册数据
     * @author 伍将
     * @date 2020/11/10
     * @param user:
     * @return com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.report.model.vo.response.MemberRegisterStatisticsVO>
     **/
    @Override
    public Wrapper<MemberRegisterStatisticsVO> getMemberRegisterList(UserLoginCacheDTO user) {

        MemberRegisterStatisticsVO result = new MemberRegisterStatisticsVO();

        // 获取角色名称
        List<MemberRoleBO> roleNameList = memberDAO.getRoleNameList();
        if (roleNameList != null && roleNameList.size() > 0) {

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String startDate;
            String endDate = DateUtil.date().toString("yyyy-MM-dd 23:59:59");
            LocalDateTime endTime = LocalDateTime.parse(endDate, formatter);
            List<String> timeList;

            // 查询近三十天数据
            startDate = DateUtil.offsetMonth(DateUtil.date(), -1).toString("yyyy-MM-dd 00:00:00");
            timeList = TimeUtil.getBetweenDays(startDate, endDate);
            LocalDateTime monthStartTime = LocalDateTime.parse(startDate, formatter);
            List<MemberDayReportDO> weekDOList = memberDayReportRepository.getAllByDateTimeBetween(monthStartTime, endTime);

            List<MemberRegisterStatisticsDetailVO> monthList = convertMemberRegisterDayStatistics(timeList, roleNameList, weekDOList);
            if (monthList.size() > 0) {

                // 设置三十日数据
                result.setMonthList(monthList);
                result.setMonthCount(monthList.stream()
                        .filter(o -> o.getDateTime().isAfter(monthStartTime) && o.getDateTime().isBefore(endTime))
                        .mapToLong(MemberRegisterStatisticsDetailVO::getCount).sum());

                // 设置七日数据
                startDate = DateUtil.offsetWeek(DateUtil.date(), -1).toString("yyyy-MM-dd 00:00:00");
                LocalDateTime weekStartTime = LocalDateTime.parse(startDate, formatter);
                List<MemberRegisterStatisticsDetailVO> weekList = monthList.stream()
                        .filter(o -> o.getDateTime().isAfter(weekStartTime) && o.getDateTime().isBefore(endTime))
                        .collect(Collectors.toList());

                result.setWeekList(weekList);
                result.setWeekCount(weekList.stream().mapToLong(MemberRegisterStatisticsDetailVO::getCount).sum());

                // 设置今日数据
                LocalDateTime todayTime = LocalDateTime.parse(DateUtil.date().toString("yyyy-MM-dd 00:00:00"), formatter);
                result.setTodayCount(weekList.stream()
                        .filter(o -> o.getDateTime().equals(todayTime))
                        .mapToLong(MemberRegisterStatisticsDetailVO::getCount).sum());
            }

            // 查询近一年数据
            startDate = DateUtil.offset(DateUtil.date(), DateField.YEAR, -1).toString("yyyy-MM-01 00:00:00");
            endDate = DateUtil.date().toString("yyyy-MM-01 00:00:00");
            LocalDateTime yearStartTime = LocalDateTime.parse(startDate, formatter);
            List<MemberMonthReportDO> yearDOList = memberMonthReportRepository.getAllByDateTimeBetween(yearStartTime, endTime);
            timeList = TimeUtil.getBetweenMonths(startDate, endDate);
            List<MemberRegisterStatisticsDetailVO> yearList = convertMemberRegisterMohthStatistics(timeList, roleNameList, yearDOList);
            result.setYearList(yearList);

            Long totalCount = memberMonthReportRepository.getAllRegisterCount();
            result.setTotalCount(totalCount != null ? totalCount : 0);
        }

        return Wrapper.success(result);
    }

    /**
     * 获取会员注册数据
     * @author 伍将
     * @date 2020/11/10
     * @param user:
     * @return com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.report.model.vo.response.MemberRegisterStatisticsVO>
     **/
    @Override
    public Wrapper<MemberRegisterStatisticsVO> getMemberRegisterListByMember(UserLoginCacheDTO user) {

        MemberRegisterStatisticsVO result = new MemberRegisterStatisticsVO();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String startDate;
        String endDate = DateUtil.date().toString("yyyy-MM-dd 23:59:59");
        LocalDateTime endTime = LocalDateTime.parse(endDate, formatter);
        List<String> timeList;

        // 查询近三十天数据
        startDate = DateUtil.offsetMonth(DateUtil.date(), -1).toString("yyyy-MM-dd 00:00:00");
        timeList = TimeUtil.getBetweenDays(startDate, endDate);
        LocalDateTime monthStartTime = LocalDateTime.parse(startDate, formatter);
        List<StatisticsMemberBO> weekDOList = subMemberReportDAO.getStatisticsGroupByDay(startDate, endDate, user.getMemberId(), user.getMemberRoleId());

        List<MemberRegisterStatisticsDetailVO> monthList = convertSubMemberRegisterDayStatistics(timeList, weekDOList);
        if (monthList.size() > 0) {

            // 设置三十日数据
            result.setMonthList(monthList);
            result.setMonthCount(monthList.stream()
                    .filter(o -> o.getDateTime().isAfter(monthStartTime) && o.getDateTime().isBefore(endTime))
                    .mapToLong(MemberRegisterStatisticsDetailVO::getCount).sum());

            // 设置七日数据
            startDate = DateUtil.offsetWeek(DateUtil.date(), -1).toString("yyyy-MM-dd 00:00:00");
            LocalDateTime weekStartTime = LocalDateTime.parse(startDate, formatter);
            List<MemberRegisterStatisticsDetailVO> weekList = monthList.stream()
                    .filter(o -> o.getDateTime().isAfter(weekStartTime) && o.getDateTime().isBefore(endTime))
                    .collect(Collectors.toList());

            result.setWeekList(weekList);
            result.setWeekCount(weekList.stream().mapToLong(MemberRegisterStatisticsDetailVO::getCount).sum());

            // 设置今日数据
            LocalDateTime todayTime = LocalDateTime.parse(DateUtil.date().toString("yyyy-MM-dd 00:00:00"), formatter);
            result.setTodayCount(weekList.stream()
                    .filter(o -> o.getDateTime().equals(todayTime))
                    .mapToLong(MemberRegisterStatisticsDetailVO::getCount).sum());
        }

        // 查询近一年数据
        startDate = DateUtil.offset(DateUtil.date(), DateField.YEAR, -1).toString("yyyy-MM-01 00:00:00");
        endDate = DateUtil.date().toString("yyyy-MM-01 00:00:00");
        LocalDateTime yearStartTime = LocalDateTime.parse(startDate, formatter);
        List<StatisticsMemberBO> yearDOList = subMemberReportDAO.getStatisticsOrderByMonth(startDate, endDate, user.getMemberId(), user.getMemberRoleId());
        timeList = TimeUtil.getBetweenMonths(startDate, endDate);
        List<MemberRegisterStatisticsDetailVO> yearList = convertSubMemberRegisterDayStatistics(timeList, yearDOList);
        result.setYearList(yearList);

        Long totalCount = memberMonthReportRepository.getAllRegisterCount();
        result.setTotalCount(totalCount != null ? totalCount : 0);

        return Wrapper.success(result);
    }



    /**
     * 转换会员日注册统计数据
     * @author 伍将
     * @date 2020/11/10
     * @param timeList:
     * @param roleNameList:
     * @param reportDOList:
     * @return java.util.List<com.ssy.lingxi.report.model.vo.response.MemberRegisterStatisticsDetailVO>
     **/
    private List<MemberRegisterStatisticsDetailVO> convertMemberRegisterDayStatistics(List<String> timeList, List<MemberRoleBO> roleNameList, List<MemberDayReportDO> reportDOList) {

        List<MemberRegisterStatisticsDetailVO> resultList = new ArrayList<>();

        if (timeList == null || timeList.size() <= 0
                || roleNameList == null || roleNameList.size() <= 0) {
            return resultList;
        }

        Map<String, Long> map = reportDOList.stream().collect(Collectors.toMap(MemberDayReportDO::getKey, MemberDayReportDO::getCount, (key1, key2) -> key2));

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 补全时间和角色
        for (String time : timeList) {
            for (MemberRoleBO roleBO : roleNameList) {
                MemberRegisterStatisticsDetailVO detailVO = new MemberRegisterStatisticsDetailVO();
                detailVO.setDateTime(LocalDateTime.parse(time + " 00:00:00", formatter));
                detailVO.setRoleName(roleBO.getRoleName());
                Long count = 0L;
                String key = (detailVO.getDateTime() + detailVO.getRoleName());
                if (map.containsKey(key)) {
                    count = map.get(key);
                }
                detailVO.setCount(count);
                resultList.add(detailVO);
            }
        }

        return resultList;
    }

    /**
     * 转换会员日注册统计数据
     * @author 伍将
     * @date 2020/11/10
     * @param timeList:
     * @param reportDOList:
     * @return java.util.List<com.ssy.lingxi.report.model.vo.response.MemberRegisterStatisticsDetailVO>
     **/
    private List<MemberRegisterStatisticsDetailVO> convertSubMemberRegisterDayStatistics(List<String> timeList ,List<StatisticsMemberBO> reportDOList) {

        List<MemberRegisterStatisticsDetailVO> resultList = new ArrayList<>();

        Map<LocalDateTime, Long> map = reportDOList.stream().collect(Collectors.toMap(StatisticsMemberBO::getDateTime, StatisticsMemberBO::getCount, (key1, key2) -> key2));

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 补全时间和角色
        for (String time : timeList) {
                MemberRegisterStatisticsDetailVO detailVO = new MemberRegisterStatisticsDetailVO();
                detailVO.setDateTime(LocalDateTime.parse(time + " 00:00:00", formatter));
                Long count = 0L;
                if (map.containsKey(detailVO.getDateTime())) {
                    count = map.get(detailVO.getDateTime()).longValue();
                }
                detailVO.setCount(count);
                resultList.add(detailVO);
        }
        return resultList;
    }

    /**
     * 转换会员月注册统计数据
     * @author 伍将
     * @date 2020/11/10
     * @param timeList:
     * @param roleNameList:
     * @param reportDOList:
     * @return java.util.List<com.ssy.lingxi.report.model.vo.response.MemberRegisterStatisticsDetailVO>
     **/
    private List<MemberRegisterStatisticsDetailVO> convertMemberRegisterMohthStatistics(List<String> timeList, List<MemberRoleBO> roleNameList, List<MemberMonthReportDO> reportDOList) {

        List<MemberRegisterStatisticsDetailVO> resultList = new ArrayList<>();

        if (timeList == null || timeList.size() <= 0
                || roleNameList == null || roleNameList.size() <= 0) {
            return resultList;
        }

        Map<String, Long> map = reportDOList.stream().collect(Collectors.toMap(MemberMonthReportDO::getKey, MemberMonthReportDO::getCount, (key1, key2) -> key2));

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 补全时间和角色
        for (String time : timeList) {
            for (MemberRoleBO roleBO : roleNameList) {
                MemberRegisterStatisticsDetailVO detailVO = new MemberRegisterStatisticsDetailVO();
                detailVO.setDateTime(LocalDateTime.parse(time + " 00:00:00", formatter));
                detailVO.setRoleName(roleBO.getRoleName());
                Long count = 0L;
                String key = (detailVO.getDateTime() + detailVO.getRoleName());
                if (map.containsKey(key)) {
                    count = map.get(key);
                }
                detailVO.setCount(count);
                resultList.add(detailVO);
            }
        }

        return resultList;
    }

    @Transactional
    @Override
    public void newlyAddedDayPurchaseReportTask() {
        logger.info("采购统计-生成昨日采购数据-start");
        //生成昨日数据
        DateTime dateTime =DateUtil.yesterday();
        newlyAddedDayPurchaseReportTaskByDate(dateTime);
        logger.info("采购统计-生成昨日采购数据-end");
    }

    /**
     * 初始化采购-采购订单、协议订单日报数据
     */
    @Transactional
    @Override
    public void initPurchaseDayReport(){
        //检测表中是否存在数据
        Pageable pageable = PageRequest.of(0 , 1);
        // 组装查询条件
        Specification<PurchaseDayReportDO> spec =  (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.gt(root.get("id"), 0));
            Predicate[] p = new Predicate[predicateList.size()];
            return cb.and(predicateList.toArray(p));
        };
        Page<PurchaseDayReportDO> all = purchaseDayReportRepository.findAll(spec, pageable);
        if(all.getTotalElements()>0){
            logger.info("初始化采购统计-数据已经存在，不再进行初始化");
            return;
        }
        //初始化3个月内的数据
        DateTime yesterday = DateUtil.yesterday();
        DateTime startDate = DateUtil.offsetMonth(yesterday, -3);
        newlyAddedDayPurchaseReportTask(startDate,yesterday);
    }

    @Transactional
    public void newlyAddedDayPurchaseReportTask(DateTime startDate,DateTime endDate){
        logger.info("采购统计-生成昨日采购数据-start :startDate{},endDate:{}",startDate,endDate);
        //生成昨日数据
//        DateTime dateTime =DateUtil.yesterday();
        List<DateTime> dateTimes = DateUtil.rangeToList(startDate, endDate, DateField.DAY_OF_YEAR);
        dateTimes.forEach(this::newlyAddedDayPurchaseReportTaskByDate);

        logger.info("采购统计-生成昨日采购数据-end");
    }

    private String getKey(PurchaseDayReportDO ent,Long startMillis){
        return startMillis+":"+ent.getMemberId()+":"+ent.getRoleId();
    }

    /**
     * 生成指定日期内采购统计记录
     * @param startDate 指定日期
     */
    private void newlyAddedDayPurchaseReportTaskByDate(DateTime startDate) {
        logger.info("日新增采购统计报表定时任务开启：" + Constants.dateFormat.format(new Date()));
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);
        LocalDateTime startTime = LocalDateTime.parse(
                DateUtil.date(startDate)
                        .toString("yyyy-MM-dd 00:00:00")
                , formatter);
        LocalDateTime endTime = LocalDateTime.parse(
                DateUtil.date(startDate)
                        .toString("yyyy-MM-dd 23:59:59")
                , formatter);
        long startMillis = startTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long endMillis = endTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        Map<String,PurchaseDayReportDO> gatherList=new HashMap<>();
        //获取日期段内采购订单总金额与次数
        List<PurchaseDayReportDO> dayOrderStatistics = procurementOrderDAO.getDayOrderStatistics(startMillis,endMillis);
        if(CollectionUtil.isNotEmpty(dayOrderStatistics)){
            gatherList= dayOrderStatistics.stream().collect(Collectors.toMap(o -> getKey(o, startMillis), o -> o));
        }
        //统计询价
        List<PurchaseDayReportDO> inquiryList = purchaseInquiryDAO.getPlatformExaminedStatisticsCount(startMillis, endMillis);
        if(CollectionUtil.isNotEmpty(inquiryList)){
            for(PurchaseDayReportDO o:inquiryList){
                String key = getKey(o, startMillis);
                PurchaseDayReportDO purchaseDayReportDO = gatherList.get(key);
                if(purchaseDayReportDO!=null){
                    long num = o.getInquiryNum() == null ? 0L : o.getInquiryNum();
                    purchaseDayReportDO.setInquiryNum(num);
                }else{
                    gatherList.put(key,o);
                }
            }
        }
        //统计招标
        List<PurchaseDayReportDO> inviteTenderList = inviteTenderDAO.getPlatformExaminedStatisticsCount(startMillis, endMillis);
        if(CollectionUtil.isNotEmpty(inviteTenderList)){
            for(PurchaseDayReportDO o:inviteTenderList){
                String key = getKey(o, startMillis);
                PurchaseDayReportDO purchaseDayReportDO = gatherList.get(key);
                if(purchaseDayReportDO!=null){
                    long num = o.getInviteTenderNum() == null ? 0L : o.getInviteTenderNum();
                    purchaseDayReportDO.setInviteTenderNum(num);
                }else{
                    gatherList.put(key,o);
                }
            }
        }
        //统计竞价
        List<PurchaseDayReportDO> biddingList = biddingDAO.getPlatformExaminedStatisticsCount(startMillis, endMillis);
        if(CollectionUtil.isNotEmpty(biddingList)){
            for(PurchaseDayReportDO o:biddingList){
                String key = getKey(o, startMillis);
                PurchaseDayReportDO purchaseDayReportDO = gatherList.get(key);
                if(purchaseDayReportDO!=null){
                    long num = o.getBiddingNum() == null ? 0L : o.getBiddingNum();
                    purchaseDayReportDO.setBiddingNum(num);
                }else{
                    gatherList.put(key,o);
                }
            }
        }
        //过滤重复后保存
        if(gatherList.size()>0){
            List<PurchaseDayReportDO> dateDbList = purchaseDayReportRepository.getAllByDateTime(startTime);
            if(CollectionUtil.isNotEmpty(dateDbList)){
                Map<String, PurchaseDayReportDO> dbMap = dateDbList.stream().collect(Collectors.toMap(o -> getKey(o, startMillis), v -> v));
                gatherList.forEach((k,v) ->{
                    v.setDateTime(startTime);
                    PurchaseDayReportDO purchaseDayReportDO = dbMap.get(k);
                    if(purchaseDayReportDO!=null){
                        v.setId(purchaseDayReportDO.getId());
                    }
                });
            }else{
                gatherList.forEach((k,v)-> v.setDateTime(startTime));
            }
            logger.info("日新增采购统计报表定时任务结束：共保存：{}条",gatherList.values().size());
            purchaseDayReportRepository.saveAll(gatherList.values());
        }
        logger.info("日新增采购统计报表定时任务结束：" + Constants.dateFormat.format(new Date()));
    }

    private BooleanBuilder getTupleListByRequest(List<PurchasePortalRequest> request,QPurchaseDayReportDO purchaseDayReportDO){
        BooleanBuilder booleanBuilder=new BooleanBuilder();
        for(PurchasePortalRequest o :request){
            BooleanBuilder andBuilder=new BooleanBuilder();
            andBuilder.and(purchaseDayReportDO.memberId.eq(o.getMemberId()));
            andBuilder.and(purchaseDayReportDO.roleId.eq(o.getRoleId()));
            booleanBuilder.orAllOf(andBuilder);
        }
       return booleanBuilder;
    }

    /**
     * 根据会员、角色id,查询采购统计数据
     * @param request 请求
     * @return 购统计数据
     */
    private List<PurchasePortalStatisticsVO> getPurchaseStatisticsList(List<PurchasePortalRequest> request){
        if(CollectionUtil.isEmpty(request)){
            return null;
        }
        QPurchaseDayReportDO purchaseDayReportDO = QPurchaseDayReportDO.purchaseDayReportDO;
        return queryFactory.select(Projections.bean(PurchasePortalStatisticsVO.class,
                purchaseDayReportDO.memberId,
                purchaseDayReportDO.roleId,
                purchaseDayReportDO.num.sum().as("num"),
                purchaseDayReportDO.amount.sum().as("amount"),
                purchaseDayReportDO.inquiryNum.sum().as("inquiryNum"),
                purchaseDayReportDO.inviteTenderNum.sum().as("inviteTenderNum"),
                purchaseDayReportDO.biddingNum.sum().as("biddingNum")
        ))
                .from(purchaseDayReportDO)
                .where(getTupleListByRequest(request,purchaseDayReportDO))
                .groupBy(purchaseDayReportDO.memberId, purchaseDayReportDO.roleId).fetch();
    }

    /**
     * 获得采购统计-采购门户首页
     * @return 采购门户首页
     */
    public Wrapper<PurchasePortalStatisticsVO> getPurchaseStatisticsByPortal(PurchasePortalRequest req){
        List<PurchasePortalStatisticsVO> purchaseStatisticsByPortal = getPurchaseStatisticsList(Collections.singletonList(req));
        if(CollectionUtil.isNotEmpty(purchaseStatisticsByPortal)){
            return Wrapper.success(Optional.ofNullable(purchaseStatisticsByPortal).flatMap(map -> map.stream().findFirst()).orElse(null));
        }
        return Wrapper.success();
    }

    @Override
    public Wrapper<List<PurchasePortalStatisticsVO>> getPurchaseStatisticsByPortal(List<PurchasePortalRequest> request) {
        return Wrapper.success(getPurchaseStatisticsList(request));
    }
}
